package server

import (
	"context"
	__ "doctor-srv/basic/proto"
	"doctor-srv/handler/models"
	"doctor-srv/untils"
	"errors"
	"github.com/google/uuid"
	"time"
)

// server is used to implement helloworld.GreeterServer.
type Server struct {
	__.UnimplementedDoctorServer
}

// SayHello implements helloworld.GreeterServer
func (s *Server) Login(_ context.Context, in *__.LoginReq) (*__.LoginResp, error) {
	var err error

	var patient models.Patient
	patient = models.Patient{
		Name:     in.Name,
		Password: in.Password,
		Age:      int(in.Age),
		Sex:      in.Sex,
		Address:  in.Address,
		CardId:   in.CardId,
	}
	if err = patient.AddPatient(); err != nil {
		return nil, errors.New("注册失败")
	}

	return &__.LoginResp{
		PatientId: int64(patient.ID),
	}, nil
}

// 医生添加
func (s *Server) AddDoctor(_ context.Context, in *__.AddDoctorReq) (*__.AddDoctorResp, error) {
	var err error

	var doctor models.Doctor
	doctor = models.Doctor{
		Name:   in.Name,
		Lever:  in.Lever,
		Depart: in.Depart,
		Desc:   in.Desc,
		Image:  in.Image,
		Number: int(in.Number),
		Status: 1, //无排版
	}
	if err = doctor.AddDoctor(); err != nil {
		return nil, errors.New("添加失败")
	}

	return &__.AddDoctorResp{
		DoctorId: int64(doctor.ID),
	}, nil
}

// 添加预约
func (s *Server) AddReservation(_ context.Context, in *__.AddReservationReq) (*__.AddReservationResp, error) {
	var err error

	//判断患者
	var patient models.Patient
	if err = patient.GetPatient(int(in.PatientId)); err != nil {
		return nil, errors.New("患者查询失败")
	}

	if patient.ID == 0 {
		return nil, errors.New("请前往登录")
	}

	var doctor models.Doctor
	if err = doctor.GetDoctor(int(in.DoctorId)); err != nil {
		return nil, errors.New("医生查询失败")
	}

	if doctor.ID == 0 {
		return nil, errors.New("该医生不存在")
	}

	//判断余额
	if doctor.Number < 1 {
		return nil, errors.New("该医生预约已满")
	}

	//锁
	untils.LockDoctorNum(int(in.DoctorId), doctor.Number)

	//解析时间
	parse, err := time.Parse(time.DateTime, in.ReservationTime)
	if err != nil {
		return nil, errors.New("时间解析失败")
	}

	var reservation models.Reservation
	reservation = models.Reservation{
		PatientId:       int(in.PatientId),
		DoctorId:        int(in.DoctorId),
		ReservationSn:   uuid.NewString(),
		ReservationTime: &parse,
		Status:          1, //未开始
	}
	if err = reservation.AddReservation(); err != nil {
		return nil, errors.New("添加预约失败")
	}

	var order models.Order
	order = models.Order{
		PatientId: int(in.PatientId),
		DoctorId:  int(in.DoctorId),
		OrderSn:   uuid.NewString(),
		Price:     in.Price,
	}
	if err = order.CreateOrder(); err != nil {
		return nil, errors.New("订单创建失败")
	}

	untils.UnLockDoctorNum(int(in.DoctorId))

	url := untils.Pay{}
	payOrder := url.PayOrder(order.OrderSn, order.Price)

	return &__.AddReservationResp{
		Url: payOrder,
	}, nil
}

// 问诊
func (s *Server) AddRecord(_ context.Context, in *__.AddRecordReq) (*__.AddRecordResp, error) {
	var err error

	var reservation models.Reservation
	if err = reservation.GetReservation(int(in.ReservationId)); err != nil {
		return nil, errors.New("预约查询失败")
	}

	if reservation.ID == 0 {
		return nil, errors.New("该预约不存在")
	}

	//判断医生
	if reservation.DoctorId != int(in.DoctorId) {
		return nil, errors.New("该预约不是您的")
	}

	//判断患者
	var patient models.Patient
	if err = patient.GetPatient(int(in.PatientId)); err != nil {
		return nil, errors.New("该患者不是您的")
	}

	if patient.CardId != in.CardId {
		return nil, errors.New("该预约没有此患者")
	}

	var record models.Record
	record = models.Record{
		PatientId:     int(in.PatientId),
		DoctorId:      int(in.DoctorId),
		ReservationId: int(in.ReservationId),
		Duration:      in.Duration,
		Status:        2, //待完成
	}

	if err = record.AddRecord(); err != nil {
		return nil, errors.New("添加失败")
	}

	return &__.AddRecordResp{
		RecordId: int64(record.ID),
	}, nil
}

// 处方添加
func (s *Server) AddPrescript(_ context.Context, in *__.AddPrescriptReq) (*__.AddPrescriptResp, error) {
	var err error

	var patient models.Patient
	if err = patient.GetPatient(int(in.PatientId)); err != nil {
		return nil, errors.New("患者查询失败")
	}

	var doctor models.Doctor
	if err = doctor.GetDoctor(int(in.DoctorId)); err != nil {
		return nil, errors.New("医生查询失败")
	}

	var record models.Record
	if err = record.GetRecord(int(in.RecordId)); err != nil {
		return nil, errors.New("该问诊不存在")
	}

	var prescript models.Prescript
	prescript = models.Prescript{
		PatientId: int(in.PatientId),
		DoctorId:  int(in.DoctorId),
		RecordId:  int(in.RecordId),
		Desc:      in.Desc,
		Status:    1, //未审核
	}
	if err = prescript.AddPrescript(); err != nil {
		return nil, errors.New("处方添加失败")
	}

	var order models.Order
	order = models.Order{
		PatientId:   int(in.PatientId),
		DoctorId:    int(in.DoctorId),
		RecordId:    int(in.RecordId),
		PrescriptId: int(prescript.ID),
		OrderSn:     uuid.NewString(),
		Price:       in.Price,
	}
	if err = order.CreateOrder(); err != nil {
		return nil, errors.New("订单创建失败")
	}

	url := untils.Pay{}
	url.PayOrder(order.OrderSn, order.Price)

	return &__.AddPrescriptResp{
		PayUrl: "url",
	}, nil
}

// 处方审核
func (s *Server) UpdatePrescript(_ context.Context, in *__.UpdatePrescriptReq) (*__.UpdatePrescriptResp, error) {
	var err error

	var prescript models.Prescript
	if err = prescript.GetPrescript(int(in.PrescriptId)); err != nil {
		return nil, errors.New("该处方查询失败")
	}

	if prescript.ID == 0 {
		return nil, errors.New("该处方不存在")
	}

	if prescript.Status != 1 {
		return nil, errors.New("该处方已审核")
	}

	prescript.Status = int(in.Status)
	if err = prescript.UpdateStatus(int(in.PrescriptId)); err != nil {
		return nil, errors.New("更新失败")
	}

	return &__.UpdatePrescriptResp{
		PrescriptId: int64(prescript.ID),
	}, nil
}

// 订单详情
func (s *Server) GetOrderDetail(_ context.Context, in *__.GetOrderDetailReq) (*__.GetOrderDetailResp, error) {
	var err error

	var order models.Order
	if err = order.GetOrder(int(in.OrderId)); err != nil {
		return nil, errors.New("订单查询失败")
	}

	var doctor models.Doctor
	if err = doctor.GetDoctor(order.DoctorId); err != nil {
		return nil, errors.New("医生查询失败")
	}

	var patient models.Patient
	if err = patient.GetPatient(order.PatientId); err != nil {
		return nil, errors.New("医生查询失败")
	}

	var prescript models.Prescript
	if err = prescript.GetPrescript(order.PrescriptId); err != nil {
		return nil, errors.New("医生查询失败")
	}

	return &__.GetOrderDetailResp{
		Name:      doctor.Name,
		Lever:     doctor.Lever,
		Depart:    doctor.Depart,
		Desc:      doctor.Desc,
		Image:     doctor.Image,
		PName:     patient.Name,
		PDesc:     prescript.Desc,
		OrderSn:   order.OrderSn,
		Price:     order.Price,
		PayMothed: int64(order.PayMothed),
		PayStatus: int64(order.PayStatus),
	}, nil
}
